package com.boarsoft.boar.job.shell;

import java.io.IOException;
import java.rmi.UnexpectedException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.boarsoft.boar.deploy.DeployConfig;
import com.boarsoft.boar.deploy.common.Constants;
import com.boarsoft.boar.job.BaseExportJob;
import com.boarsoft.boar.job.BaseRestartJob;
import com.boarsoft.boar.job.BaseShutdownJob;
import com.boarsoft.boar.job.BaseStartJob;
import com.boarsoft.boar.job.BuildCompiler;
import com.boarsoft.boar.job.BuildExporter;
import com.boarsoft.boar.job.BuildJob;
import com.boarsoft.boar.job.ICompileJob;
import com.boarsoft.boar.job.IDeployer;
import com.boarsoft.boar.job.IExportJob;
import com.boarsoft.boar.job.jenkins.JenkinsCompileJob;
import com.boarsoft.boar.job.jenkins.JenkinsDeployJob;
import com.boarsoft.common.util.HttpClientUtil;

public class ShellBroker implements IDeployer, BuildCompiler,BuildExporter {
	@Override
	public void restartByJenkins(BaseRestartJob mainJob) throws UnexpectedException {

	}

	@Override
	public void startByJenkins(BaseStartJob mainJob) throws UnexpectedException {

	}

	private static Logger log = LoggerFactory.getLogger(ShellBroker.class);
	private static Map<String, ShellBroker> instancesMap = new ConcurrentHashMap<String, ShellBroker>();
	/*
	 * 部署报文体
	 */
	Map<String, String> deploySendMsg = new HashMap<String, String>();
	/*
	 * 部署报文体
	 */
	Map<String, String> compileSendMsg = new HashMap<String, String>();
	/**
	 * 本实例负责处理的主构建的ID
	 */
	private String id;
	private ShellDeploymentJob mainJob;
	/**
	 * 拆解后的子构建列表部署信息:
	 * BUILD_INDEX
	 * DEPLOY_STATUS
	 */
	private List<Map<String, String>> subJobList = new ArrayList<Map<String, String>>();
	/**
	 * 当前正在执行的子构建的索引号
	 */
	private int currentIndex;
	private int completedJobCount;
	private int failedJobCount;


	public ShellBroker(String id) {
		this.id = id;
	}

	public static Map<String, ShellBroker> getInstancesMap() {
		return instancesMap;
	}

	public static void setInstancesMap(Map<String, ShellBroker> instancesMap) {
		ShellBroker.instancesMap = instancesMap;
	}

	public List<Map<String, String>> getSubJobList() {
		return subJobList;
	}

	public void setSubJobList(List<Map<String, String>> subJobList) {
		this.subJobList = subJobList;
	}

	/*
	 * 输入串input为空串"", 或者null时，抛出异常，异常信息为info
	 */
	private void chkString(String input, String info) throws UnexpectedException {

		if (null == input || "".equals(input)) {
			log.error(JSON.toJSONString(info));
			throw new UnexpectedException(info);
		}

	}

	/*
	 * 检查公用部分输入项
	 */
	private void chkInputPubInfo(BuildJob job) throws UnexpectedException {

		chkString(job.getCallBackUrl(), "callBackUrl not null");
		chkString(job.getCplEnv(), "cplEnv not null");
		// chkString(job.getProjectRoot(), "projectRoot not null");
		chkString(job.getBuildCode(), "buildCode not null");
		chkString(job.getSourceCode(), "sourceCode not null");
		chkString(job.getSourceServer(), "SourceServer not null");
		chkString(job.getSourceRoot(), "SourceRoot not null");
		chkString(job.getSourceParent(), "sourcePath not null");
		chkString(job.getSourcePath(), "sourcePath not null");

	}

	/*
	 * 检查deploy输入项
	 */
	private void chkInputDeployInfo(ShellDeploymentJob job) throws UnexpectedException {

		if (null == job.getAppIpList() || job.getAppIpList().size() < 1) {
			log.error(JSON.toJSONString("appIpList not null"));
			throw new UnexpectedException("appIpList not null");
		}
		chkString(job.getAppName(), "appName not null");
		// chkString(job.getDeployType(), "deployType not null");
		// if (null == job.getDeployType()) {
		// log.error(JSON.toJSONString("deployType not null"));
		// throw new UnexpectedException("deployType not null");
		// }
		chkString(job.getDeployPolicy(), "deployFlag not null");
		if (Constants.DEPLOY_TYPE_JAR_LIST == job.getDeployType()) {
			chkString(job.getAppJarList(), "appJarList not null");
		}

	}

	/*
	 * 设置post包体公用部分
	 *
	 */
	private void setPubMsg(BuildJob job, Map<String, String> msg) {

		msg.put(Constants.TARGET_ID, job.getTargetId());
		msg.put(Constants.CALL_BACK_URL, job.getCallBackUrl());
		msg.put(Constants.JOB_ID, this.id);
		msg.put(Constants.CPL_ENV, job.getCplEnv());

		if (null == job.getAppVsn() || "".equals(job.getAppVsn())) {
			msg.put(Constants.APP_VSN, DeployConfig.LOCAL_TARGET_VSN);
		} else {
			msg.put(Constants.APP_VSN, job.getAppVsn());
		}

		msg.put(Constants.SOURCE_CODE_KEY, job.getSourceCode());
		msg.put(Constants.SOURCE_SERVER_KEY, job.getSourceServer());
		msg.put(Constants.SOURCE_ROOT_KEY, job.getSourceRoot());
		msg.put(Constants.SOURCE_PARENT_KEY, job.getSourceParent());
		msg.put(Constants.SOURCE_PATH_KEY, job.getSourcePath());

	}

	/*
	 * 设置post包体公用部分
	 *
	 */
	private void setDeployPostMsg(ShellDeploymentJob mainJob, Map<String, String> msg) {

		setPubMsg(mainJob, msg);

		msg.put(Constants.APP_NAME, mainJob.getAppName());
		msg.put(Constants.APP_USR, DeployConfig.REMOTE_APP_USR);
		msg.put(Constants.APP_UPLOAD, DeployConfig.REMOTE_APP_UPLOAD);
		msg.put(Constants.APP_SBIN, DeployConfig.REMOTE_APP_SBIN);
		msg.put(Constants.APP_HOME, DeployConfig.REMOTE_APP_HOME);
		msg.put(Constants.DEPLOY_TYPE, String.valueOf(mainJob.getDeployType()));
		msg.put(Constants.JAR_LIST, mainJob.getAppJarList());

	}

	/*
	 * 初始化子构建列表
	 *
	 */
	private void iniPubSubJobList(List<String> ipList) {
		Map<String, String> deployInfo;

		for (int i = 0; i < ipList.size(); i++) {
			deployInfo = new HashMap<String, String>();
			deployInfo.put(Constants.BUILD_INDEX, String.valueOf(i));
			deployInfo.put(Constants.DEPLOY_STATUS_KEY,
					Constants.DEPLOY_STATUS_A);
			deployInfo.put(Constants.DEPLOY_IP_KEY, ipList.get(i));
			this.subJobList.add(deployInfo);
		}

	}

	/*
	 * 并发调用jenkins构建进行部署
     * mainJob --
     * sendMsg --
     * startIndex -- 连表subJobList起始下标, 下标起始值为0
     * num -- 并发部署数目
	 */
	private int doDeployConc(ShellDeploymentJob mainJob, Map<String, String> sendMsg,
	                         int startIndex, int num) throws IOException {

		String rs;
		String deployUrl;
		String buildName;
		Map<String, String> cloneMsg = new HashMap<String, String>();

		log.info(JSON.toJSONString("startIndex[" + startIndex + "], " + "num[" + num
				+ "], " + "subJobList size[" + this.subJobList.size() + "], "));

		if (this.subJobList.size() < startIndex + num || startIndex < 0 || num <= 0) {
			log.error(JSON.toJSONString("parameter error: startIndex[" + startIndex
					+ "], " + "num[" + num + "], " + "subJobList size["
					+ this.subJobList.size() + "], "));
			throw new UnexpectedException("parameter error: startIndex[" + startIndex
					+ "], " + "num[" + num + "], " + "subJobList size["
					+ this.subJobList.size() + "], ");
		}

		for (int i = startIndex; i < startIndex + num; i++) {

			this.setCurrentIndex(i);

			/*
			 * clone jenkins构建
			 */
			deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
					.concat(Constants.DEPLOY_CREATE_ITEM_VAL);
			buildName = this.id.concat("_").concat(String.valueOf(i));
			cloneMsg.put(Constants.DEPLOY_CREATE_NAME_KEY, buildName);
			cloneMsg.put(Constants.DEPLOY_CREATE_MODE_KEY,
					Constants.DEPLOY_CREATE_MODE_VAL);
			cloneMsg.put(Constants.DEPLOY_CREATE_FROM_KEY, mainJob.getBuildCode());
			rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
					cloneMsg, null, null);

			/*
			 * 将clone的构建设置为禁用
			 */
			deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
					.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/")
					.concat(buildName).concat("/")
					.concat(Constants.DEPLOY_CREATE_DISABLE);
			rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
					sendMsg, null, null);

			/*
			 * 将clone的构建设置为可用
			 */
			deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
					.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/")
					.concat(buildName).concat("/")
					.concat(Constants.DEPLOY_CREATE_ENABLE);
			rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
					sendMsg, null, null);

			/*
			 * 调起jenkins构建
			 */
			deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
					.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/")
					.concat(buildName).concat("/")
					.concat(Constants.DEPLOY_CREATE_BUILD_VAL);
			sendMsg.put(Constants.BUILD_INDEX, String.valueOf(i));
			sendMsg.put(Constants.APP_IP, this.subJobList.get(i).get(Constants.DEPLOY_IP_KEY));
			rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
					sendMsg, null, null);
			log.info(JSON.toJSONString("sendPost return: [" + rs + "]"));
			if (!"".equals(rs)) {
				log.error(JSON.toJSONString("sendPost return: [" + rs + "]"));
				throw new UnexpectedException("sendPost return: [" + rs + "]");
			}
		}

		return 0;
	}

	/*
	 * 按ip列表顺序部署, 只负责调起第一个节点, 等收到该节点回执后执行后续部署
	 */
	private void doDeployQueue(ShellDeploymentJob mainJob, Map<String, String> sendMsg)
			throws IOException {

		doDeployConc(mainJob, sendMsg, 0, 1);

	}

	/*
	 * 半数并发部署, 只负责调起前一半节点, 等收到前一半节点所有回执后执行后续部署
	 */
	private void doDeployHalfConc(ShellDeploymentJob mainJob,
	                              Map<String, String> sendMsg) throws IOException {

		log.info("app list size={} ", mainJob.getAppIpList().size());
		int tmp;
		doDeployConc(mainJob, sendMsg, 0,
				(tmp = mainJob.getAppIpList().size() / 2) == 0 ? 1 : tmp);

	}

	/*
	 * 全量并发部署
	 */
	private void doDeployAllConc(ShellDeploymentJob mainJob,
	                             Map<String, String> sendMsg) throws IOException {

		log.info("app list size={}", mainJob.getAppIpList().size());
		doDeployConc(mainJob, sendMsg, 0, mainJob.getAppIpList().size());

	}

	@Override
	public void deployByJenkins(JenkinsDeployJob mainJob) throws UnexpectedException {
//		this.deploy(mainJob);
	}

	@Override
	public void shutDownByJenkins(BaseShutdownJob mainJob) throws UnexpectedException {

	}

	@Override
	public void deployByShell(ShellDeploymentJob mainJob) throws IOException {
		this.deploy(mainJob);
	}

	private void deploy(ShellDeploymentJob mainJob) throws IOException {

		log.info(JSON.toJSONString("start JenkinsBroker"));

		this.mainJob = mainJob;
		chkInputPubInfo(this.mainJob);
		chkInputDeployInfo(this.mainJob);
		// TODO 获取目标服务器列表
		// 遍历列表按目标服务器，将主构建拆分为子构建
		iniPubSubJobList(this.mainJob.getAppIpList());

		setDeployPostMsg(mainJob, this.deploySendMsg);
		this.deploySendMsg.put("job_id", this.id);

		// 根据部署策略决定如何调起
		switch (this.mainJob.getDeployPolicy()) {
			// 如果是“逐一部署”，调起第一个
			case Constants.DEPLOY_FLAG_0:
				doDeployQueue(this.mainJob, this.deploySendMsg);
				break;

			// 如果是“半数启停”，调起lt.size()/2个
			case Constants.DEPLOY_FLAG_1:
				doDeployHalfConc(this.mainJob, this.deploySendMsg);
				break;

			// 如果是“全停全启”，全部调起
			case Constants.DEPLOY_FLAG_2:
				doDeployAllConc(this.mainJob, this.deploySendMsg);
				break;

			default:
				log.error(JSON.toJSONString("input deploy flag [" + "" + "] error"));
				throw new UnexpectedException("input deploy flag [" + "" + "] error");
		}

		log.info(JSON.toJSONString("end JenkinsBroker deploy"));

	}

	/*
	 * 收到响应后, 更新相关信息;
	 */
	private void updateSubJobStatus(ShellBroker shellDep, int index, String status)
			throws UnexpectedException {

		log.info("update status: id={}, index={},status={},subJobList.size={}", shellDep.id, index, this.subJobList.size());
		if (index >= this.subJobList.size()) {
			log.error("input index={},subJobList size={}", index, this.subJobList.size());
			throw new UnexpectedException("input index[" + index + "], "
					+ "subJobList size[" + this.subJobList.size() + "]");
		}

		switch (status) {
			// case BuildKey.DEPLOY_STATUS_0:
			// break;

			case Constants.DEPLOY_STATUS_0: // 成功
				shellDep.setCompletedJobCount(shellDep.getCompletedJobCount() + 1);
				break;

			case Constants.DEPLOY_STATUS_2: // 失败
				shellDep.setFailedJobCount(shellDep.getFailedJobCount() + 1);
				break;

			default:
				log.error(JSON.toJSONString("input status flag [" + status + "] error"));
				throw new UnexpectedException("input status flag [" + status + "] error");
		}

		shellDep.subJobList.get(index).put(Constants.DEPLOY_STATUS_KEY, status);

	}

	/*
	 * 顺序部署回调处理
	 */
	private void doJobCompletedQueue(ShellBroker shellDep, int index, String status)
			throws IOException {

		updateSubJobStatus(shellDep, index, status);

		// 全部部署完毕
		if (index >= shellDep.subJobList.size() - 1) {
			log.info("deploy id={} complete", shellDep.id);
			log.info("deploy succeed num={},deploy failure num={}", shellDep.getCompletedJobCount(), shellDep.getFailedJobCount());

			// destroyInstance(shellDep.id);
			return;
		}

		// 当前节点部署成功或者失败，继续部署下一节点
		if (Constants.DEPLOY_STATUS_0.equals(status)
				|| Constants.DEPLOY_STATUS_2.equals(status)) {
			log.debug("begin: id {},index ", shellDep.id, index + 1);
			doDeployConc(shellDep.mainJob, shellDep.deploySendMsg, index + 1, 1);
		}
		// else: 收到状态为"开始构建", do nothing;

	}

	/*
	 * 半数并发回调处理
	 */
	private void doJobCompletedHalfConc(ShellBroker shellDep, int index,
	                                    String status) throws IOException {

		int tmp;

		updateSubJobStatus(shellDep, index, status);

		// 全部部署完毕
		if (shellDep.getCompletedJobCount() + shellDep.getFailedJobCount() >= shellDep.subJobList.size()) {
			log.info("deploy id {} complete", shellDep.id);
			log.info("deploy succeed num={},deploy failure num={}", shellDep.getCompletedJobCount(), shellDep.getFailedJobCount());

			// destroyInstance(shellDep.id);
			return;
		}

		if (index < ((tmp = shellDep.subJobList.size() / 2) == 0 ? 1 : tmp)) { // 当前节点为前半部分节点
			if (shellDep.getCompletedJobCount() + shellDep.getFailedJobCount() == tmp) { // 前半部分节点都已收到响应
				// 调起后半部分节点
				doDeployConc(shellDep.mainJob, shellDep.deploySendMsg, tmp, shellDep.subJobList.size() - tmp);
			} // else: do nothing;
		} else if (index >= shellDep.subJobList.size()) {
			log.error("error: index {},size={}", index, shellDep.subJobList.size());
			throw new UnexpectedException("error: index[" + index + "], " + "size["
					+ shellDep.subJobList.size() + "]");
		}

	}

	/*
	 * 全量并发回调处理
	 */
	private void doJobCompletedAllConc(ShellBroker jenkinsDep, int index, String status)
			throws UnexpectedException {

		updateSubJobStatus(jenkinsDep, index, status);

		// 全部部署完毕
		if (jenkinsDep.getCompletedJobCount()
				+ jenkinsDep.getFailedJobCount() >= jenkinsDep.subJobList.size()) {
			log.info(JSON.toJSONString("deploy id [" + jenkinsDep.id + "] complete"));
			log.info(JSON.toJSONString("deploy succeed num["
					+ jenkinsDep.getCompletedJobCount() + "], " + "deploy failure num["
					+ jenkinsDep.getFailedJobCount() + "]"));

			// destroyInstance(shellDep.id);
		}

	}

	/*
	 * 部署后回调处理
	 */
	@Override
	public void onJobCompleted(String id, int index, String status)
			throws IOException {
		log.info(JSON.toJSONString(
				"id=[" + id + "], index=[" + index + "], status=[" + status + "]"));
		// 获取当前instance
		ShellBroker curBroker = getInstance(id);
		log.info(JSON.toJSONString(
				"deployPolicy=[" + curBroker.mainJob.getDeployPolicy() + "]"));
		// 根据部署策略决定如何调起
		switch (curBroker.mainJob.getDeployPolicy()) {
			// “逐一部署”
			case Constants.DEPLOY_FLAG_0:
				doJobCompletedQueue(curBroker, index, status);
				break;

			// “半数启停”
			case Constants.DEPLOY_FLAG_1:
				doJobCompletedHalfConc(curBroker, index, status);
				break;

			// “全停全启”
			case Constants.DEPLOY_FLAG_2:
				doJobCompletedAllConc(curBroker, index, status);
				break;

			default:
				log.error(JSON.toJSONString("input deploy flag ["
						+ curBroker.mainJob.getDeployPolicy() + "] error"));
				ShellBroker.getInstancesMap().put(id, curBroker);
				throw new UnexpectedException("input deploy flag ["
						+ curBroker.mainJob.getDeployPolicy() + "] error");
		}
		ShellBroker.getInstancesMap().put(id, curBroker);
	}

	/*
	 * 检查export输入项
	 */
	private void chkInputExportInfo(BaseExportJob job) throws UnexpectedException {

		// chkString(job.getSourceRoot(), "sourceRoot not null");
		chkString(job.getCompType(), "compType not null");
		// chkString(job.getSourceServer(), "sourceServer not null");

	}

	private void setExportSendMsg(BaseExportJob mainJob, Map<String, String> msg) {
		setPubMsg(mainJob, msg);

		msg.put(Constants.BUILD_INDEX, "0");
		msg.put(Constants.SOURCE_ROOT_KEY, mainJob.getSourceRoot());
		if (!(null == mainJob.getSrcRevision() || "".equals(mainJob.getSrcRevision())))
			msg.put(Constants.SRC_REVISION_KEY, mainJob.getSrcRevision());
		if (!(null == mainJob.getPackType() || "".equals(mainJob.getPackType())))
			msg.put(Constants.PACKAGE_TYPE_KEY, mainJob.getPackType());
		if (!(null == mainJob.getMvnCompComm() || "".equals(mainJob.getMvnCompComm())))
			msg.put(Constants.MVN_COMP_COMM_KEY, mainJob.getMvnCompComm());
		msg.put(Constants.COMPILE_TYPE_KEY, mainJob.getCompType());
		// msg.put(BuildKey.SRC_USER_KEY, DeployConfig.SRC_USER);
		// msg.put(BuildKey.SRC_PASS_KEY, DeployConfig.SRC_PASS);
		msg.put(Constants.SOURCE_SERVER_KEY, mainJob.getSourceServer());

	}

	/*
	 * 检查compile输入项
	 */
	private void chkInputCompileInfo(JenkinsCompileJob job) throws UnexpectedException {

		// chkString(job.getSourceRoot(), "sourceRoot not null");
		chkString(job.getCompType(), "compType not null");
		// chkString(job.getSourceServer(), "sourceServer not null");

	}

	private void setCompileSendMsg(JenkinsCompileJob mainJob, Map<String, String> msg) {
		setPubMsg(mainJob, msg);

		msg.put(Constants.BUILD_INDEX, "0");
		msg.put(Constants.SOURCE_ROOT_KEY, mainJob.getSourceRoot());
		if (!(null == mainJob.getSrcRevision() || "".equals(mainJob.getSrcRevision())))
			msg.put(Constants.SRC_REVISION_KEY, mainJob.getSrcRevision());
		if (!(null == mainJob.getPackType() || "".equals(mainJob.getPackType())))
			msg.put(Constants.PACKAGE_TYPE_KEY, mainJob.getPackType());
		if (!(null == mainJob.getMvnCompComm() || "".equals(mainJob.getMvnCompComm())))
			msg.put(Constants.MVN_COMP_COMM_KEY, mainJob.getMvnCompComm());
		msg.put(Constants.COMPILE_TYPE_KEY, mainJob.getCompType());
		// msg.put(BuildKey.SRC_USER_KEY, DeployConfig.SRC_USER);
		// msg.put(BuildKey.SRC_PASS_KEY, DeployConfig.SRC_PASS);
		msg.put(Constants.SOURCE_SERVER_KEY, mainJob.getSourceServer());

	}

	@Override
	public void buildExportJob(IExportJob mainJob) throws IOException {
		this.export(mainJob);
	}

	private void export(IExportJob mainJob) throws IOException {
		BaseExportJob exportJob = (BaseExportJob) mainJob;

		String rs;
		String deployUrl;
		String buildName;
		Map<String, String> cloneMsg = new HashMap<String, String>();

		chkInputPubInfo(exportJob);
		chkInputExportInfo(exportJob);
		setExportSendMsg(exportJob, compileSendMsg);

		/*
		 * clone jenkins构建
		 */
		buildName = "compile".concat(this.id);
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_ITEM_VAL);
		cloneMsg.put(Constants.DEPLOY_CREATE_NAME_KEY, buildName);
		cloneMsg.put(Constants.DEPLOY_CREATE_MODE_KEY,
				Constants.DEPLOY_CREATE_MODE_VAL);
		cloneMsg.put(Constants.DEPLOY_CREATE_FROM_KEY, exportJob.getBuildCode());
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				cloneMsg, null, null);

		/*
		 * 将clone的构建设置为禁用
		 */
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/").concat(buildName)
				.concat("/").concat(Constants.DEPLOY_CREATE_DISABLE);
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				compileSendMsg, null, null);

		/*
		 * 将clone的构建设置为可用
		 */
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/").concat(buildName)
				.concat("/").concat(Constants.DEPLOY_CREATE_ENABLE);
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				compileSendMsg, null, null);

		/*
		 * 调起jenkins构建
		 */
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/").concat(buildName)
				.concat("/").concat(Constants.DEPLOY_CREATE_BUILD_VAL);
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				compileSendMsg, null, null);
		log.info(JSON.toJSONString("sendPost return: [" + rs + "]"));
		if (!"".equals(rs)) {
			log.error(JSON.toJSONString("sendPost return: [" + rs + "]"));
			throw new UnexpectedException("sendPost return: [" + rs + "]");
		}

		destroyInstance(this.id);
	}

	@Override
	public void buildCompileJob(ICompileJob mainJob) throws IOException {
		this.compile(mainJob);
	}

	private void compile(ICompileJob mainJob) throws IOException {
		JenkinsCompileJob compileJob = (JenkinsCompileJob) mainJob;

		String rs;
		String deployUrl;
		String buildName;
		Map<String, String> cloneMsg = new HashMap<String, String>();

		chkInputPubInfo(compileJob);
		chkInputCompileInfo(compileJob);
		setCompileSendMsg(compileJob, compileSendMsg);

		/*
		 * clone jenkins构建
		 */
		buildName = "compile".concat(this.id);
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_ITEM_VAL);
		cloneMsg.put(Constants.DEPLOY_CREATE_NAME_KEY, buildName);
		cloneMsg.put(Constants.DEPLOY_CREATE_MODE_KEY,
				Constants.DEPLOY_CREATE_MODE_VAL);
		cloneMsg.put(Constants.DEPLOY_CREATE_FROM_KEY, compileJob.getBuildCode());
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				cloneMsg, null, null);

		/*
		 * 将clone的构建设置为禁用
		 */
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/").concat(buildName)
				.concat("/").concat(Constants.DEPLOY_CREATE_DISABLE);
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				compileSendMsg, null, null);

		/*
		 * 将clone的构建设置为可用
		 */
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/").concat(buildName)
				.concat("/").concat(Constants.DEPLOY_CREATE_ENABLE);
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				compileSendMsg, null, null);

		/*
		 * 调起jenkins构建
		 */
		deployUrl = DeployConfig.DEPLOY_CREATE_URL_VAL.concat("/")
				.concat(Constants.DEPLOY_CREATE_JOB_VAL).concat("/").concat(buildName)
				.concat("/").concat(Constants.DEPLOY_CREATE_BUILD_VAL);
		rs = HttpClientUtil.sendPost(deployUrl, "UTF-8", "UTF-8",
				compileSendMsg, null, null);
		log.info(JSON.toJSONString("sendPost return: [" + rs + "]"));
		if (!"".equals(rs)) {
			log.error(JSON.toJSONString("sendPost return: [" + rs + "]"));
			throw new UnexpectedException("sendPost return: [" + rs + "]");
		}

		destroyInstance(this.id);
	}

	public ShellBroker getInstance(String id) {
		if (!getInstancesMap().containsKey(id)) {
			getInstancesMap().put(id, new ShellBroker(id));
		}
		return getInstancesMap().get(id);
	}

	public void destroyInstance(String id) {
		getInstancesMap().remove(id);
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public int getCompletedJobCount() {
		return completedJobCount;
	}

	public void setCompletedJobCount(int completedJobCount) {
		this.completedJobCount = completedJobCount;
	}

	public int getFailedJobCount() {
		return failedJobCount;
	}

	public void setFailedJobCount(int failedJobCount) {
		this.failedJobCount = failedJobCount;
	}

	public int getCurrentIndex() {
		return currentIndex;
	}

	public void setCurrentIndex(int currentIndex) {
		this.currentIndex = currentIndex;
	}

}
